﻿using System;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Text;
using CompactMapper.Orm.Extensions;
using CompactMapper.Orm.UnitOfWork.Commands.Interfaces;
using CompactMapper.Orm.UnitOfWork.Mappings;

namespace CompactMapper.Orm.UnitOfWork.Commands.Implementations
{
    internal sealed class CreateTableCommand : Command, ICreateTableCommand
    {
        private readonly String _cmdText;


        public CreateTableCommand(Table table, TablesTree tablesTree)
            : base(table)
        {
            _cmdText = CreateTableTextWithForeignKey(Table, tablesTree);
        }
        private static String CreateTableTextWithForeignKey(Table table, TablesTree tablesTree)
        {
            var builder = new SqlBuilder().CreateTable(table);
            table.Relationships.Apply(relationship => builder.CreateJoinTable(relationship, tablesTree));
            return builder.ToString();
        }


        public void Run(SQLiteConnection connection)
        {
            var cmd = new SQLiteCommand(_cmdText, connection);
            cmd.ExecuteNonQuery();
        }


        private const char OpenParentheses = '(';
        private const char CloseParentheses = ')';
        private const char Comma = ',';
        private const char Semicolon = ';';
        private const char Tab = '\t';
        private const char Newline = '\n';
        public void OutputSql(TextWriter outputBuilder)
        {
            var commandText = _cmdText;
            var firstParentheses = commandText.IndexOf(OpenParentheses);
            var tableDeclaration = commandText.Substring(0, firstParentheses);
            var allcolumns = commandText.Substring(firstParentheses + 1).Split(Comma).OfType<String>();


            var theText = new StringBuilder(tableDeclaration).Append(Newline).Append(OpenParentheses).Append(Newline);
            var lastColumn = allcolumns.Last();
            var otherThanLast = allcolumns.Take(allcolumns.Count() - 1);
            otherThanLast.Apply(column => theText.Append(Tab).Append(column).Append(Comma).Append(Newline));
            theText.Append(Tab).Append(lastColumn).Remove(theText.Length - 2, 2).Append(Newline).Append(CloseParentheses)
                .Append(Semicolon);
            outputBuilder.WriteLine(theText.ToString());
        }
    }
}